package com.fosu.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fosu.Utils.JwtTokenUtil;
import com.fosu.Utils.RedisUtil;
import com.fosu.common.ResponseResult;
import com.fosu.vo.UserDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

/**
 * @author zqa
 * 一次请求只通过一次filter，不需要重复执行
 * @version 1.0
 * @date 2020/10/30 11:38
 */

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
    @Value("${token.expirationMilliSeconds}")
    private long expirationMilliSeconds;


    @Autowired
    RedisUtil redisUtil;


    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        System.out.println("过滤器1");
        String authHeader = request.getHeader("Authorization");//获取请求头的信息  请求头的key叫Authorization
        response.setCharacterEncoding("utf-8");//设置网页字符集UTF-8
        if (authHeader == null || !authHeader.startsWith("Bearer ")) {
            filterChain.doFilter(request, response);//token格式不正确
            return;
        }
        String authToken = authHeader.substring("Bearer ".length());
        System.out.println(authToken);

        //获取redis中的token信息
        if (!redisUtil.hasKey(authToken)) {
            //token 不存在 返回错误信息
            response.getWriter().write(JSON.toJSONString(ResponseResult.bulid("未登录或登录过期1", null)));
            response.setStatus(500);
            return;
        }


        //获取Redis中的信息
        HashMap<String, Object> hashMap = (HashMap<String, Object>) redisUtil.hget(authToken);

        UserDetail userDetail = new UserDetail();  //保存数据到userDetail对象
        Set authoritiesSet = new HashSet();
        String s = hashMap.get("authorities").toString();
        s = s.substring(1, s.length() - 1);
        System.out.println(s);

        if (s.contains(",")) {
            String a[] = s.split(",");
            System.out.println(a[1]);
            int c[] = new int[a.length];
            for (int i = 0; i < a.length; i++) {
                a[i] = a[i].substring(1, a[i].length() - 1);
                c[i] = a[i].indexOf("=") + 1;
                System.out.println(a[i]);
                System.out.println(c[i]);
                authoritiesSet.add(new SimpleGrantedAuthority(a[i].substring(c[i])));
                System.out.println(a[i].substring(c[i]));
                System.out.println(authoritiesSet);
            }

            userDetail.setAuthorities(authoritiesSet);

        } else {
            s = s.substring(0, s.length() - 1);
            authoritiesSet.add(new SimpleGrantedAuthority(s.substring(s.indexOf("=") + 1)));
            System.out.println(s.substring(s.indexOf("=") + 1));
            System.out.println(authoritiesSet);
            userDetail.setAuthorities(authoritiesSet);
        }


        userDetail.setOpenId(String.valueOf(hashMap.get("id"))).setAuthorities(authoritiesSet);

        if (null == hashMap) {
            //token 不存在 返回错误信息
            response.getWriter().write(JSON.toJSONString(ResponseResult.bulid("未登录或登录过期2", null)));
            response.setStatus(500);
            return;
        }
        //更新token过期时间
        redisUtil.setKeyExpire(authToken, expirationMilliSeconds);

        //将信息交给security
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetail, null, userDetail.getAuthorities());
        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);//将得到的Authentication实例放入Holder
        filterChain.doFilter(request, response);


    }
}
